﻿fly.regPlugin('combo', function ($) {
    var ui = $.ui;
    $.ui.Combo = $.Class({
        base: ui.Panel,
        wrap: null,
        constructor: function (config) {
            var me = this
            arguments.callee.$base.apply(this, arguments)
            this.items = config ? config.items : null,
            this.createMembers()
            this.bindEvents();
            this.selectDefault();
        },
        items: null,
        baseCss: "f-combo",
        domFrame: ["wrap", "pad"],
        textFormat: '{text}',
        itemFormat: '<div f-id="{id}" class="f-combo-item">{text}</div>',
        padFormat: '<div class="f-combo-pad"></div>',
        padWidth: '100%',
        hideOnClickPad: true,
        onBeforeCreatePad: $.Event.createEventFn("beforecreatepad"),
        createPad: function () {
            if (this.padCreated)
                return;

            this.onBeforeCreatePad();
            if (!this.pad) {
                this.pad = $(this.padFormat);

                var pad = this.pad.filter('.f-combo-pad');
                pad.length || (pad = this.pad.find('.f-combo-pad'));
                pad.length || (pad = this.pad);
                pad.empty();
            }
            else {
                this.pad = $(this.pad);
                this.pad.addClass("f-combo-pad");
            }



            if (this.content) {
                this.pad.append(this.content);
            }
            else if (this.items) {
                this.itemMap = {};
                this.items.each(function (item, i) {
                    var el = $.isDom(item) ? item : ($.isDom(item.text) ? item.text : $(this.itemFormat.format(item)))
                    this.itemMap[item.id] = el;
                    pad.append(el);
                }, this);
            }
            this.pad.appendTo(document.body);
        },
        showPad: function () {
            this.createPad();

            var rect = this.wrap.rect();
            if (this.padWidth) {
                this.pad.width(/%/.test(this.padWidth) ? rect.width * parseFloat(this.padWidth) / 100 - 2 : this.padWidth)
            }

            if (this.padHeight) {
                this.pad.height(this.padHeight)
            }

            var top = rect.top + rect.height + document.documentElement.scrollTop;
            var left = rect.left + document.documentElement.scrollLeft;
            this.pad.show()

            var padWidth = this.pad.offset().width
            if (rect.width > padWidth) {
                left += (rect.width - padWidth) / 2
            }
            this.pad.css({ left: left, top: top, display: 'block' });
        },
        selectItem: function (item) {
            var text = this.textFormat.format(item);
            if (this.textBox[0].nodeName == "INPUT") {
                this.textBox.value(text);
            }
            else {
                this.textBox.html(text);
            }

            this.selectedItem = item;
            this.selectedValue = item.id;
            this.hidden && this.hidden.value(item.id);
        },
        selectDefault: function () {
            var me = this;
            var item = me.selectedItem
            if (!item && me.items) {
                var value = me.selectedValue || this.hidden.value()
                if (value) {
                    item = me.items.first(function (item) {
                        return item.id == value;
                    })
                }
                item = item || this.items.first()
            }
            item && this.selectItem(item);
        },
        createMembers: function () {
            var me = this;
            this.wrap = $(this.wrap || this.selector || ('#' + this.id))
            this.wrap.comboBox = this;
            this.textBox = this.wrap.$(".f-combo-text")
            this.textBox[0] || (this.textBox = this.wrap.filter("input"))
            this.textBox[0] || (this.textBox = this.wrap.$("input"))
            this.textBox.addClass("f-combo-text");
            this.arrow = this.wrap.$(".f-combo-arrow")
            var hiddenName = this.hiddenName || this.id || this.wrap.attr('hidden') || this.wrap.id();

            if (hiddenName) {
                var form = $(document.forms).first(function () {
                    return !!this[hiddenName]
                });

                if (form)
                    this.hidden = $(form[hiddenName])
                else
                    this.hidden = $('<input type=hidden name="{0}" />'.format(hiddenName)).insertAfter(this.wrap);
            }
        },
        bindEvents: function () {
            var me = this;

            $.doc.click(function () {
                var target = $($event.target);
                var item = target.closest(".f-combo-item");
                if (item.length) {
                    me.value(item.attr("f-id"));
                    setTimeout(function () {
                        me.pad.hide()
                    }, 60);
                }
                else if (me.wrap[0] == target[0] || $.DomHelper.contains(me.wrap[0], target[0])) {
                    me.showPad()
                }
                else if (me.pad) {
                    if (!me.hideOnClickPad && (me.pad[0] == target[0] || $.DomHelper.contains(me.pad[0], target[0]))) {
                        return
                    }
                    me.pad.hide()
                }
            });


        },
        text: function (text) {
            if (arguments.length) {
                //this.textBox.html(text);
                this.textBox.value(text);
                return this;
            }
            else {
                return this.textBox.html();
            }
        },
        value: function (val) {
            if (arguments.length) {
                var item = this.items.first(function (o) {
                    return o.id == val;
                })
                if (!item)
                    throw "not find item:" + val;
                this.selectItem(item);
                return this;
            }
            else {
                return this.selectedValue;
            }

            //            if (arguments.length) {
            //                this.textBox.html(val)
            //            }
            //            else {
            //                return this.textBox.html();
            //            }
        }
    })
    $.Component.Mgr.regType("combo", $.ui.Combo);
});


fly.regPlugin('combotree', function ($) {
    var ui = $.ui;
    $.ui.ComboTree = $.Class({
        base: $.ui.Combo,
        constructor: function (config) {
            var me = this
            arguments.callee.$base.apply(this, arguments)
            this.onBeforeCreatePad(this.createTree, this);
        },
        createTree: function () {
            var me = this;
            var notTree = !(this.tree instanceof fly.mini.Tree)
            if (!this.pad || notTree) {
                if (notTree) {
                    fly.mini.ajax = $.ajax;
                    var isMulti = this.tree.selectionMode == fly.mini.selectionMode.multi;
                    var config = {
                        leastSelectionOne: true,
                        onSelect: function (item, fireByDom) {
                            if (isMulti) {
                                clearTimeout(me.changeHandler);
                                me.changeHandler = setTimeout(function () {
                                    var items = me.tree.getSelectItems();
                                    me.text(items.select("o=>o.text").join(","));
                                    me.value(items.select("o=>o.id").join(","));
                                }, 10);
                                return false;
                            }
                            else {
                                if (fireByDom && item.selected) {
                                    me.selectItem(item)
                                }
                            }
                        }
                    }
                    if (isMulti) {
                        config.checkMode = fly.mini.checkMode.multi
                        config.keepCheckAndSelectSync = true
                        this.hideOnClickPad = false;
                    }

                    this.tree = new fly.mini.Tree($.extendIf(this.tree, config));
                }
                this.tree.render(document.body)
                this.pad = this.tree.root.wrap
            }
        },
        value: function (val) {
            if (arguments.length) {
                this.hidden.value(val);
                return this;
            }
            else {
                return this.hidden.value();
            }
        }
    })
    $.Component.Mgr.regType("combotree", $.ui.Combo);
});